package com.path.planning.controller;

import com.deductive.common.core.controller.BaseController;
import com.deductive.common.core.domain.AjaxResult;
import com.path.planning.algorithm.RoutingEngine;
import com.path.planning.entity.RoutingCountry;
import com.path.planning.entity.RoutingNetwork;
import com.path.planning.entity.RoutingRequest;
import com.path.planning.entity.RoutingResult;
import com.path.planning.mapper.RoutingMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.io.WKTReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 路径规划控制器
 */
@Api(tags = "路径规划管理")
@RestController
@RequestMapping("/routing")
public class RoutingController extends BaseController {

    @Autowired
    private RoutingEngine routingEngine;

    @Autowired
    private RoutingMapper routingMapper;

    private final WKTReader wktReader = new WKTReader();

    /**
     * 路径规划
     */
    @ApiOperation("路径规划")
    @PostMapping("/plan")
    public AjaxResult planRoute(@RequestBody Map<String, Object> request) {
        try {
            // 解析请求参数
            String startWkt = (String) request.get("startPoint");
            String endWkt = (String) request.get("endPoint");
            String countryCode = (String) request.get("countryCode");
            Double maxDistance = request.get("maxDistance") != null ? 
                Double.valueOf(request.get("maxDistance").toString()) : 50000.0;
            Double searchRadius = request.get("searchRadius") != null ? 
                Double.valueOf(request.get("searchRadius").toString()) : 1000.0;

            // 验证参数
            if (startWkt == null || endWkt == null || countryCode == null) {
                return error("起点、终点和国家代码不能为空");
            }

            // 解析几何数据
            Point startPoint = (Point) wktReader.read(startWkt);
            Point endPoint = (Point) wktReader.read(endWkt);

            // 构建请求对象
            RoutingRequest routingRequest = new RoutingRequest(startPoint, endPoint, countryCode);
            routingRequest.setMaxDistance(maxDistance);
            routingRequest.setSearchRadius(searchRadius);

            // 执行路径规划
            RoutingResult result = routingEngine.findRoute(routingRequest);

            if (result.getSuccess()) {
                return success(result);
            } else {
                return error(result.getErrorMessage());
            }

        } catch (Exception e) {
            logger.error("路径规划失败", e);
            return error("路径规划失败: " + e.getMessage());
        }
    }

    /**
     * 获取支持的国家列表
     */
    @ApiOperation("获取支持的国家列表")
    @GetMapping("/countries")
    public AjaxResult getCountries() {
        try {
            List<Map<String, String>> countries = new ArrayList<>();
            List<RoutingCountry> countryList = routingMapper.getAllCountries();
            
            for (RoutingCountry country : countryList) {
                Map<String, String> countryMap = new HashMap<>();
                countryMap.put("code", country.getCountryCode());
                countryMap.put("name", country.getCountryName());
                countries.add(countryMap);
            }
            
            return success(countries);
        } catch (Exception e) {
            logger.error("获取国家列表失败", e);
            return error("获取国家列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取路网统计信息
     */
    @ApiOperation("获取路网统计信息")
    @GetMapping("/stats")
    public AjaxResult getNetworkStats(@ApiParam("国家代码") @RequestParam(required = false) String countryCode) {
        try {
            if (countryCode != null && !countryCode.trim().isEmpty()) {
                // 获取指定国家的统计信息
                RoutingMapper.NetworkStatistics stats = routingMapper.getNetworkStatistics(countryCode);
                if (stats == null) {
                    return error("未找到指定国家的路网数据");
                }
                return success(stats);
            } else {
                // 获取所有国家的统计信息
                List<RoutingMapper.NetworkStatistics> allStats = routingMapper.getAllNetworkStatistics();
                return success(allStats);
            }
        } catch (Exception e) {
            logger.error("获取路网统计信息失败", e);
            return error("获取统计信息失败: " + e.getMessage());
        }
    }

    /**
     * 检查路网数据状态
     */
    @ApiOperation("检查路网数据状态")
    @GetMapping("/status")
    public AjaxResult getNetworkStatus(@ApiParam("国家代码") @RequestParam String countryCode) {
        try {
            // 检查国家是否存在
            if (!routingMapper.countryExists(countryCode)) {
                return error("不支持的国家代码: " + countryCode);
            }

            // 获取表名
            String tableName = routingMapper.getTableNameByCountryCode(countryCode);
            if (tableName == null) {
                return error("无法获取国家对应的路网表");
            }

            // 获取路网数据统计
            long networkCount = routingMapper.getNetworkCount(tableName);
            double totalLength = routingMapper.getTotalLength(tableName);

            Map<String, Object> status = new HashMap<>();
            status.put("countryCode", countryCode);
            status.put("tableName", tableName);
            status.put("hasData", networkCount > 0);
            status.put("networkCount", networkCount);
            status.put("totalLength", totalLength);
            status.put("status", networkCount > 0 ? "数据已就绪" : "暂无数据");

            return success(status);
        } catch (Exception e) {
            logger.error("检查路网状态失败", e);
            return error("检查路网状态失败: " + e.getMessage());
        }
    }

    /**
     * 查找附近的路网段
     */
    @ApiOperation("查找附近的路网段")
    @GetMapping("/nearby")
    public AjaxResult findNearbyNetworks(
            @ApiParam("国家代码") @RequestParam String countryCode,
            @ApiParam("中心点WKT") @RequestParam String centerWkt,
            @ApiParam("搜索半径(米)") @RequestParam(defaultValue = "1000") Double radius,
            @ApiParam("最大数量") @RequestParam(defaultValue = "10") Integer limit) {
        try {
            // 检查国家是否存在
            if (!routingMapper.countryExists(countryCode)) {
                return error("不支持的国家代码: " + countryCode);
            }

            // 获取表名
            String tableName = routingMapper.getTableNameByCountryCode(countryCode);
            if (tableName == null) {
                return error("无法获取国家对应的路网表");
            }

            // 解析中心点
            Point centerPoint = (Point) wktReader.read(centerWkt);

            // 查找附近的路网段
            List<RoutingNetwork> networks = routingMapper.findInRadius(
                tableName, centerPoint, radius, limit);

            return success(networks);
        } catch (Exception e) {
            logger.error("查找附近路网段失败", e);
            return error("查找失败: " + e.getMessage());
        }
    }

    /**
     * 根据ID查找路网段
     */
    @ApiOperation("根据ID查找路网段")
    @GetMapping("/network/{countryCode}/{id}")
    public AjaxResult getNetworkById(
            @ApiParam("国家代码") @PathVariable String countryCode,
            @ApiParam("路网段ID") @PathVariable Long id) {
        try {
            // 检查国家是否存在
            if (!routingMapper.countryExists(countryCode)) {
                return error("不支持的国家代码: " + countryCode);
            }

            // 获取表名
            String tableName = routingMapper.getTableNameByCountryCode(countryCode);
            if (tableName == null) {
                return error("无法获取国家对应的路网表");
            }

            RoutingNetwork network = routingMapper.findById(tableName, id);
            if (network == null) {
                return error("未找到指定的路网段");
            }
            return success(network);
        } catch (Exception e) {
            logger.error("查找路网段失败", e);
            return error("查找失败: " + e.getMessage());
        }
    }
}
